#include "GL/opengl.h"

#include "Render.h"

namespace Render
{
	bool init(const char *name, uint32_t width, uint32_t height)
	{
		if (glfwInit() != GL_TRUE)
		{
			LOG_ERROR("Can't initialize GLFW\n");
			return false;
		}
		
		glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3);
		glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 3);
		glfwOpenWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
		glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 
		
		if (glfwOpenWindow(width, height, 8, 8, 8, 8, 24, 0, GLFW_WINDOW) != GL_TRUE)
		{
			LOG_ERROR("Can't create GLFW window\n");
			return false;
		}
		
		glewExperimental = GL_TRUE;
		if (glewInit() != GLEW_OK)
		{
			LOG_ERROR("Can't initialize GLEW\n");
			return false;
		}
		
		if (!GLEW_VERSION_3_3)
		{
			LOG_ERROR("OpenGL 3.3 dosen't supported\n");
			return false;
		}
		
		glfwSetWindowTitle(name);
		/*glfwSetWindowSizeCallback(glfw_resize_callback);
		glfwSetMouseButtonCallback(glfw_mouse_callback);
		glfwSetMousePosCallback(glfw_cursor_callback);*/
		
		glViewport(0, 0, width, height);
		
		glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
		glClearDepth(1.0f);
		
		glEnable(GL_DEPTH_TEST);
		glEnable(GL_CULL_FACE);
		
		return true;
	}
	
	void free()
	{
		glfwTerminate();
	}
	
	void beginFrame()
	{
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	}
	
	void endFrame()
	{
		glfwSwapBuffers();
	}
	
	void drawModel(const Model *model)
	{
		ASSERT(model);
		
		const Resource::MeshHead &mesh = model->getMesh();
		
		glBindVertexArray(model->getHandle());
		//glDrawElements(GL_TRIANGLES, mesh.head.icount, GL_UNSIGNED_INT, GL_PVOID(0));
		
		for (uint32_t i = 0; i < mesh.head.scount; ++i)
		{
			glDrawElements(GL_TRIANGLES, mesh.subsets[i].icount, GL_UNSIGNED_INT,
				GL_PVOID(mesh.subsets[i].ioffset * sizeof(uint32_t)));
		}
	}
	
	void drawText(const Font *font, uint32_t color, float x, float y, const char *str)
	{
		ASSERT(font);
		ASSERT(str);
		
		const Resource::FontHead &head = font->getFont();
		
		while (uint8_t ch = *str++)
		{
			const int32_t rect[4] = {
				head.glyphs[ch].x, head.glyphs[ch].y,
				head.glyphs[ch].w, head.glyphs[ch].h
			};
			
			if (rect[3] && rect[4])
			{
				//renderQuad(texture, setupQuad(texture, rect, color,
				//	x + head.glyphs[ch].xoff, y - headt.glyphs[ch].yoff, 99));
			}
			
			x += head.glyphs[ch].xadv;
		}
	}
}
